package com.hmsproject.db.inmemorydb;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.hmsproject.datastructures.Hotel;
import com.hmsproject.datastructures.deal.Criterion;
import com.hmsproject.datastructures.deal.Deal;
import com.hmsproject.datastructures.deal.DealDetails;
import com.hmsproject.datastructures.enums.DealTypeEnum;
import com.hmsproject.datastructures.event.Event;
import com.hmsproject.datastructures.event.EventSchedule;


public class DealMap {
	
	public static  DealMap INSTANCE = new DealMap();
	
	private Map<String,Deal> dealMapper;
	
	private DealMap(){
		dealMapper = new HashMap<String,Deal>();
		
		try{
			populateDealMap();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	
	
	
	public Map<String, Deal> getDealMapper() {
		return dealMapper;
	}

	public List<Deal> getDealsBasedOnEventId(String eventId){
		return Collections.emptyList();
	}

	private void populateDealMap() throws Exception{
		SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); 
		 
		String cutOffStr1 = "2014-12-20";
		Criterion criterion11 = new Criterion("0", 5, 2);
		Criterion criterion12 = new Criterion("0", 15, 5);
		List<Criterion> criterionList1 = new ArrayList<Criterion>();
		criterionList1.add(criterion11);
		criterionList1.add(criterion12);
		DealDetails dealDetails1 = new DealDetails(criterionList1 , ft.parse(cutOffStr1));
		EventSchedule eventSchedule1 = new EventSchedule(ft.parse("2014-12-25"), ft.parse("2014-12-30")) ;
		Event event1 = new Event("XMAS event", "SanFrancisco", eventSchedule1);
		List<Event> events1 = new ArrayList<Event>();
		events1.add(event1);
		Deal deal1  = new Deal("XMAS offer","129367",dealDetails1, events1);
		dealMapper.put(deal1.getDealId(),deal1);
		
		String cutOffStr2 = "2014-12-25";
		Criterion criterion21 = new Criterion("0", 4, 3);
		Criterion criterion22 = new Criterion("0", 15, 6);
		List<Criterion> criterionList2 = new ArrayList<Criterion>();
		criterionList2.add(criterion21);
		criterionList2.add(criterion22);
		DealDetails dealDetails2 = new DealDetails(criterionList2 , ft.parse(cutOffStr2));
		EventSchedule eventSchedule2 = new EventSchedule(ft.parse("2014-12-31"), ft.parse("2015-01-05")) ;
		Event event2 = new Event("New year event", "SanFrancisco", eventSchedule2);
		List<Event> events2 = new ArrayList<Event>();
		events2.add(event2);
		Deal deal2  = new Deal("New Year offer","106066",dealDetails2, events2);
		dealMapper.put(deal2.getDealId(),deal2);	
		
		String cutOffStr3 = "2015-03-25";
		Criterion criterion31 = new Criterion("0", 6, 4);
		Criterion criterion32 = new Criterion("0", 18, 7);
		List<Criterion> criterionList3 = new ArrayList<Criterion>();
		criterionList3.add(criterion31);
		criterionList3.add(criterion32);
		DealDetails dealDetails3 = new DealDetails(criterionList3 , ft.parse(cutOffStr3));
		EventSchedule eventSchedule3 = new EventSchedule(ft.parse("2015-04-01"), ft.parse("2015-04-05")) ;
		Event event3 = new Event("Spring event", "SanFrancisco", eventSchedule3);
		List<Event> events3 = new ArrayList<Event>();
		events3.add(event3);
		Deal deal3  = new Deal("Spring offer","115718",dealDetails3, events3);
		dealMapper.put(deal3.getDealId(),deal3);	
		
		
		String cutOffStr4 = "2015-11-05";
		Criterion criterion41 = new Criterion("0", 7, 2);
		Criterion criterion42 = new Criterion("0", 19, 8);
		List<Criterion> criterionList4 = new ArrayList<Criterion>();
		criterionList4.add(criterion41);
		criterionList4.add(criterion42);
		DealDetails dealDetails4 = new DealDetails(criterionList4 , ft.parse(cutOffStr4));
		EventSchedule eventSchedule4 = new EventSchedule(ft.parse("2015-11-11"), ft.parse("2015-11-16")) ;
		Event event4 = new Event("Diwali event", "SanFrancisco", eventSchedule4);
		List<Event> events4 = new ArrayList<Event>();
		events4.add(event4);
		Deal deal4  = new Deal("Diwali offer","112932",dealDetails4, events4);
		dealMapper.put(deal4.getDealId(),deal4);		
	}
	
	public Deal getDeal(String dealId){
		return dealMapper.get(dealId);
	}
	
	public void addDeal(Deal deal){
		dealMapper.put(deal.getDealId(), deal);
	}
	
	public Deal getDeal(String hotelid, Date checkinDate, Date checkoutDate){
		
		Deal deal = null;
		
		Collection<Deal> dealList = dealMapper.values();
		
		Iterator<Deal> iterator = dealList.iterator();
		
		while(iterator.hasNext()){
			Deal tmpdeal = iterator.next();
			if(tmpdeal.getHotelId().equals(hotelid)){
				List<Event> events = tmpdeal.getEvents();
				Iterator<Event> eventIterator = events.iterator();
				while(eventIterator.hasNext()){
					Event tmpevent = eventIterator.next();
					if(tmpevent.getEventSchedule().equals(new EventSchedule(checkinDate,checkoutDate))){
						break;
					}
				}
			}
			
			deal = tmpdeal;
			break;
		}
		
		return deal;
	}
	
	public Deal getDealForHotel(String hotelid){
		
		Deal deal = null;
		
		Collection<Deal> dealList = dealMapper.values();
		
		Iterator<Deal> iterator = dealList.iterator();
		
		while(iterator.hasNext()){
			Deal tmpdeal = iterator.next();
			if(tmpdeal.getHotelId().equals(hotelid)){
				deal = tmpdeal;
				break;
			}
		}
		
		return deal;
	}	
	
	public List<Deal> getDeals(DealTypeEnum dealTypeEnum, String hotelid){
		
		List<Deal> deals = new ArrayList<Deal>();
		
		
		if(dealTypeEnum == DealTypeEnum.ALL){
			Collection<Deal> dealList = dealMapper.values();
			Iterator<Deal> iterator = dealList.iterator();
			while(iterator.hasNext()){
				Deal tmpdeal = iterator.next();
				if(tmpdeal.getHotelId().equals(hotelid)){
					deals.add(tmpdeal);
				}
			}
			
			return deals;
		}
		
		if(dealTypeEnum == DealTypeEnum.ACTIVE){
			
			Collection<Deal> dealList = dealMapper.values();
			Iterator<Deal> iterator = dealList.iterator();
			while(iterator.hasNext()){
				Deal tmpdeal = iterator.next();
				if(tmpdeal.getHotelId().equals(hotelid) && tmpdeal.isActive()){
					deals.add(tmpdeal);
				}
			}		
			
			return deals;
			
		}
		
		if(dealTypeEnum == DealTypeEnum.NON_ACTIVE){
			
			Collection<Deal> dealList = dealMapper.values();
			Iterator<Deal> iterator = dealList.iterator();
			while(iterator.hasNext()){
				Deal tmpdeal = iterator.next();
				if(tmpdeal.getHotelId().equals(hotelid) && !tmpdeal.isActive()){
					deals.add(tmpdeal);
				}
			}		
			
			return deals;
			
		}		
		
		return deals;
	}	
	
	public String fetchHotels(Date checkinDate,Date checkoutDate,String location)
	{
		String hotelIdList = "";
		
		Collection<Deal> dealList = dealMapper.values();
		
		Iterator<Deal> iterator = dealList.iterator();
		
		if(iterator.hasNext()){
			Deal tmpdeal = iterator.next();
			hotelIdList = getHotelId(hotelIdList, checkinDate, checkoutDate, location, tmpdeal);
		}
		
		while(iterator.hasNext()){
			Deal tmpdeal = iterator.next();
			hotelIdList = ',' + getHotelId(hotelIdList, checkinDate, checkoutDate, location, tmpdeal);
		}
		
		return hotelIdList;
	}
	
	private String getHotelId(String hotelIdList,Date checkinDate,Date checkoutDate,String location,Deal deal){
		
		if(!deal.isActive()){
			return hotelIdList;
		}
		
		List<Event> events = deal.getEvents();
		Iterator<Event> eventIterator = events.iterator();
		while(eventIterator.hasNext()){
			Event tmpevent = eventIterator.next();
			if(tmpevent.getEventLocation().equals(location) && tmpevent.getEventSchedule().equals(new EventSchedule(checkinDate,checkoutDate))){
				hotelIdList = deal.getHotelId();
				break;
			}
		}
		
		return hotelIdList;
	}

	public List<Deal> getDealList(String eventId){
		
		List<Deal> dealListReturn = new ArrayList<Deal>();
		
		Collection<Deal> dealList = dealMapper.values();
		
		Iterator<Deal> iterator = dealList.iterator();

		while(iterator.hasNext()){
			Deal tmpdeal = iterator.next();
			
			if(tmpdeal.getEvents().contains(EventMap.getInstance().getEvent(eventId))){
				dealListReturn.add(tmpdeal);
			}
		}		
		
		return dealListReturn;
	}		
	
}
